package com.open.capacity.user.service.impl;


import com.open.capacity.commons.Result;
import com.open.capacity.exception.BusinessException;
import com.open.capacity.finance.config.Globals;
import com.open.capacity.finance.util.uuid.UUIDUtils;
import com.open.capacity.model.system.LoginAppUser;
import com.open.capacity.model.system.SysRole;
import com.open.capacity.user.dao.SysCompanyDao;
import com.open.capacity.user.model.SysCompany;
import com.open.capacity.user.model.SysPermission;
import com.open.capacity.user.service.SysCompanyService;
import com.open.capacity.user.service.SysPermissionService;
import com.open.capacity.user.vo.SysCompanyExcel;
import com.open.capacity.user.vo.SysCompanyVo;
import com.open.capacity.utils.SysUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    private SysCompanyDao companyDao;

    @Autowired
    private SysPermissionService permissionService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SysCompany sysCompany) {
        sysCompany.setCreateTime(new Date());
        sysCompany.setUpdateTime(sysCompany.getCreateTime());

        companyDao.save(sysCompany);

        List<SysCompany> list = companyDao.findList(new HashMap<>());
        Globals.companyList = list;

        log.info("保存机构：{}", sysCompany);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(SysCompany sysCompany) {
        sysCompany.setUpdateTime(new Date());

        companyDao.updateByOps(sysCompany);

        List<SysCompany> list = companyDao.findList(new HashMap<>());
        Globals.companyList = list;

        log.info("修改机构：{}", sysCompany);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) throws Exception {
        SysCompany sysCompany = companyDao.findById(id);
        Assert.notNull(sysCompany, "机构信息不存在");

        companyDao.delete(id);

        log.info("删除机构：{}", sysCompany);
    }


    @Override
    public SysCompany findById(String id) {
        return companyDao.findById(id);
    }

    @Override
    public List<SysCompany> findCompanys(Map<String, Object> params) {
//        //设置分页信息，分别是当前页数和每页显示的总记录数【记住：必须在mapper接口中的方法执行之前设置该分页信息】
//        if (MapUtils.getInteger(params, "page") != null && MapUtils.getInteger(params, "limit") != null)
//            PageHelper.startPage(MapUtils.getInteger(params, "page"), MapUtils.getInteger(params, "limit"), true);
        List<SysCompany> list = new ArrayList<>();
        LoginAppUser loginAppUser = SysUserUtil.getLoginAppUser();
        Set<SysRole> roles = loginAppUser.getSysRoles();


        //三权判定
        if (loginAppUser.getId().equals("1")) {//超级管理员 或者 设置员
            list = companyDao.findList(params);
        } else if (!CollectionUtils.isEmpty(roles)) {
            List<SysPermission> permissionList = new ArrayList<>();
            roles.forEach(r -> {
                permissionList.addAll(permissionService.findByObject("Role", r.getId().toString()));
            });
            if (!CollectionUtils.isEmpty(permissionList)) {
                if (permissionList.stream().map(SysPermission::getItemType).filter(item -> item.equals(0)).count() > 0) { //全部机构
                    list = companyDao.findList(params);
                } else if (permissionList.stream().map(SysPermission::getItemType).filter(item -> item.equals(1)).count() > 0) { //本机构所有账套
                    params.put("id", loginAppUser.getCompanyId());
                    list = companyDao.findList(params);
                } else if (permissionList.stream().map(SysPermission::getItemType).filter(item -> item.equals(9)).count() > 0) { //自定义
                    List<String> ids = permissionList.stream().filter(item -> item.getItemType().equals(9)).map(SysPermission::getItemId).distinct().collect(Collectors.toList());
                    params.put("ids", ids);
                    list = companyDao.findList(params);
                }
            }
        }

        return list;
    }

    @Override
    public List<SysCompany> findByParentId(String parentId) {
        return companyDao.findByParentId(parentId);
    }

    @Override
    public SysCompany findByCode(String code) {
        return companyDao.findByCode(code);
    }

    @Override
    public List<SysCompany> findAll(Map<String, Object> params) {
        List<SysCompany> list = companyDao.findList(params);
        return list;
    }


    @Override
    public Map<String, SysCompanyVo> getMap() {
        Map<String, SysCompanyVo> map = new HashMap<>();
        Map<String, Object> params = new HashMap<>();
        List<SysCompany> list = companyDao.findList(params);
        SysCompanyVo vo;
        for (SysCompany item : list) {
            vo = new SysCompanyVo();
            vo.setParentId(item.getParentId());
            vo.setName(item.getFullName());
            map.put(item.getId(), vo);
        }
        return map;
    }


    @Override
    public Result saveOrUpdate(SysCompany sysCompany, String keyValue) throws Exception {
        int i = 0;
        if (sysCompany.getParentId() == null || sysCompany.getParentId().equals("-1") || sysCompany.getParentId().equals("")) {
            sysCompany.setParentId("0");
        }
        if (StringUtils.isNotEmpty(keyValue)) {
            SysCompany model = companyDao.findById(keyValue);
            if (model != null) {
                sysCompany.setId(keyValue);
                sysCompany.setUpdateTime(new Date());
                i = companyDao.updateByOps(sysCompany);
            }
        } else {

            SysCompany exists = findByCode(sysCompany.getCode());
            if (exists != null) {
                throw new BusinessException("机构号冲突");
            }

            sysCompany.setId(UUIDUtils.getOriginalUUIDWithoutBar());
            sysCompany.setCreateTime(new Date());
            sysCompany.setUpdateTime(sysCompany.getCreateTime());
            i = companyDao.save(sysCompany);
        }

        return i > 0 ? Result.succeed("操作成功") : Result.failed("操作失败");
    }


    @Override
    public List<SysCompanyExcel> findExcels(Map<String, Object> params) {
        List<SysCompany> list = companyDao.findList(params);
        List<SysCompanyExcel> result = new ArrayList<>();
        for (SysCompany company : list) {
            SysCompanyExcel excel = new SysCompanyExcel();
            BeanUtils.copyProperties(company, excel);
            result.add(excel);
        }
        return result;
    }
}
